package logic.weapons;

import sound.AudioManager;
import factories.EffectFactory;
import gameStates.network.IDObject;
import input.StraightForwardBinding;
import logic.nodes.MoveForwardController;
import logic.nodes.collision.CollidableNode;
import logic.nodes.lod.blocks.LeafBlock;
import logic.ships.Ship;
import logic.trails.WeaponFireTrail;
import main.InitGame;

import com.jme.input.controls.GameControl;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.state.MaterialState;

public abstract class WeaponFire extends CollidableNode implements IDObject {
	
	private static final long serialVersionUID = 1L;
	
	protected WeaponProperties props;
	protected Ship ship;
	protected WeaponFireController fireController;
	protected MoveForwardController moveForwardController;
	protected MaterialState materialState;
	
	protected WeaponFireTrail trail;
	protected Vector3f dir;
	
	protected int weaponFireID;
	
	protected Weapon weapon;
	
	public WeaponFire(String name, Node model, Ship ship, Vector3f startLoc, WeaponProperties props, 
			Vector3f dir, Weapon weapon, boolean dummy) {
		super(name, "WeaponFire", model, ship.getIngameState());
		this.ship = ship;
		this.props = props;
		this.dir = dir;
		this.weapon = weapon;
		
		getLocalTranslation().set(startLoc);
		
		if(!dummy && canMove()) createMoveForwardController();
		
		createTrail();
		
		lockNode();
	}
	
	public void createMoveForwardController() {
		GameControl forward = StraightForwardBinding.getGameControl(StraightForwardBinding.forward);
		GameControl backward = StraightForwardBinding.getGameControl(StraightForwardBinding.backward);
		
		float forwardSpeed = props.getSpeed();
		
		moveForwardController = new WeaponFireMoveController(this, forward, forwardSpeed, backward);
		addController(moveForwardController);
		addMovingController(moveForwardController);
	}
	
	@Override
	protected void lockThis() {
		super.lockThis();
		lockShadows();
	}
	
	protected void createTrail() {
		if(!WeaponFireVisibility.isNeverVisibleTo(this, ingameState.getCam().getLocation())) {
			trail = new WeaponFireTrail(1f, this);
			attachChild(trail);
		}
	}
	
	public void destroy() {
		if(trail != null) trail.deleteTrail();
		removeFromParent();
		setIsCollidable(false);
		InitGame.get().getNetworkState().unregisterWeaponFire(this);
	}
	
	public void impact() {
		impact(getLocalTranslation());
	}
	
	public void impact(Vector3f loc) {
		Vector3f camLoc = ingameState.getCam().getLocation();
		float dist = camLoc.distance(getLocalTranslation());
		
		if(dist <= LeafBlock.particleDist && getParent() != null) {
			AudioManager.get().playSound(AudioManager.EXPLOSION_01, getLocalTranslation());
			EffectFactory.createWeaponExplosion(getParent(), loc);
		}
		destroy();
	}
	
	@Override
	public boolean canMove() {	return true; }
	
	@Override
	public boolean testAgainstWeaponFire() { return false; }
	
	@Override
	public Vector3f getMoveDirection() { return fireController.getFireDirection().normalize(); }
	
	public int getDamage() { return props.getDamage(); }
	
	public Ship getShip() { return ship; }
	
	@Override
	public int getID() { return weaponFireID; }
	
	@Override
	public void setID(int weaponFireID) { this.weaponFireID = weaponFireID; }
	
	public Vector3f getDirection() { return dir; }
	
	public Weapon getWeapon() { return weapon; }
	
	public boolean isWeaponFireOf(Ship ship) { return this.ship == ship; }
}